﻿package bdz.common.display
{
	
	import bdz.common.graphics.MarchingAntsRect;
	import bdz.controls.ControlElement;
	
	import com.adobe.images.JPGEncoder;
	import com.gskinner.geom.ColorMatrix;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.*;
	/**
	 * ...
	 * @author ...
	 */
	public class EditableImage extends DisplayLoader
	{
		
		private var matrix:ColorMatrix;
		private var croprect:MarchingAntsRect;
		private var controls:ControlElement;
		private var mrect:Rectangle;
		private var marq:MovieClip = new MovieClip();
		private var isource:String;
		
		
		private var image:MovieClip;
		private var _brightness:Number = 0;
		private var _contrast:Number = 0;
		private var _saturation:Number = 0;
		private var _hue:Number = 0;
		private var previous:Array = new Array();
		private var targ:*;
		private var edits:Number = 0;
		private var fdimension:Object;
		private var mholder:MovieClip;
		function EditableImage(source:String = null) {
			
			isource = source;
			super(source);
		}
		override protected function initializeComponent(evt:*=null):void {
			super.initializeComponent();
			if(isource){
				source = isource;
			}
			holder.visible = false;	
		}
		override protected function completeHandler(evt:Event):void {
			
			
			previous[edits] = new Bitmap(new BitmapData(holder.width, holder.height));
			previous[edits].bitmapData.draw(holder);
			addChild(previous[edits]);
			
			controls = new ControlElement(previous[edits], stage);
			//controls.enabled = controls.visible = false;
			
			croprect = new MarchingAntsRect([0x000000, 0xffffff], [2, 2]);
			addChild(croprect);
			
			
			super.completeHandler(evt);
			
		}
		private function saveLastInfo():void {
			removeChild(previous[edits]);
			edits++;
		}
		private function updateTransform(evt:Event = null ):void {
			
			previous[edits].transform.matrix = controls.transformMatrix;
		}
		
		private function applyColors() {
			
			matrix = new ColorMatrix(new Array());
			matrix.adjustColor(_brightness, _contrast, _saturation, _hue);
			previous[edits].filters = [new ColorMatrixFilter(matrix)]
		}
		private function onMarqueeDown(evt:MouseEvent):void {
			if (forceDimension) {
				try {
					removeChild(mholder);
				}catch (e:Error) {
					
				}
				mholder = new MovieClip();
				addChild(mholder);
				
				
			}
			addEventListener(MouseEvent.MOUSE_MOVE, updateMarquee);
			mrect = new Rectangle(mouseX, mouseY, 1, 1);
			marq.graphics.clear();
			setChildIndex(marq, numChildren - 1);
		}
		private function onMarqueeUp(evt:MouseEvent):void {
			try {
				removeChild(mholder);
			}catch (e:Error) {
				
			}
			removeEventListener(MouseEvent.MOUSE_MOVE, updateMarquee);
		}
		private function updateMarquee(evt:Event):void {
			if (forceDimension) {
				
				mholder.graphics.clear();
				mholder.graphics.lineStyle(0, 0, 0);
				mholder.graphics.beginFill(0x000000, .3);
				mholder.graphics.drawRect(mouseX, mouseY, forceDimension.width, forceDimension.height);
				mholder.graphics.endFill();
				
				mrect.x = mouseX;
				mrect.y = mouseY;
				mrect.width = forceDimension.width;
				mrect.height = forceDimension.height;
				
				
				
			}else{
				mrect.width = mouseX - mrect.x;
				mrect.height = mouseY - mrect.y;
			}
			croprect.draw(marq, mrect, 100, 100);
		}
		public function getCompressedImage(quality:Number = 80):* {
			//updateTransform();
			applyColors();
			var jpg:JPGEncoder = new JPGEncoder(quality);
			var bdata:BitmapData = new BitmapData(width, height);
			bdata.draw(previous[edits].bitmapData, previous[edits].transform.matrix);
			var nbmp:BitmapData = new BitmapData(previous[edits].width, previous[edits].height);
			var brect:Rectangle = new Rectangle(previous[edits].x, previous[edits].y, previous[edits].width, previous[edits].height)
			nbmp.copyPixels(bdata, brect, new Point());
			matrix = new ColorMatrix(new Array());
			matrix.adjustColor(_brightness, _contrast, _saturation, _hue);
			nbmp.applyFilter(nbmp, new Rectangle(0, 0, nbmp.width, nbmp.height), new Point(), new ColorMatrixFilter(matrix));
			var barray:ByteArray = jpg.encode(nbmp);
			bdata.dispose();
			//return nbmp;
			nbmp.dispose();
			return barray;
			
		}
		public function createModifier():void {
			
			controls.newTarget = previous[edits];
			removeEventListener(MouseEvent.MOUSE_DOWN, onMarqueeDown);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMarqueeUp);
			removeEventListener(MouseEvent.MOUSE_UP, onMarqueeUp);
			controls.visible = true;
			controls.enabled = true;
			
			marq.graphics.clear();
			addEventListener(Event.ENTER_FRAME, updateTransform);
		}
		public function createMarquee(rect:Rectangle = null):void {
			try {
				removeChild(marq);
			}catch (e:Error) {
				
			}
			addEventListener(MouseEvent.MOUSE_DOWN, onMarqueeDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, onMarqueeUp);
			addEventListener(MouseEvent.MOUSE_UP, onMarqueeUp);
			if (!contains(marq)) {
				addChild(marq);
			}
			setChildIndex(previous[edits], 0);
			
			controls.visible = false;
			controls.enabled = false;
			
			
			
		}
		public function applyCrop() {
			if(mrect){
				removeEventListener(Event.ENTER_FRAME, updateTransform);
				
				removeEventListener(MouseEvent.MOUSE_DOWN, onMarqueeDown);
				stage.removeEventListener(MouseEvent.MOUSE_UP, onMarqueeUp);
				removeEventListener(MouseEvent.MOUSE_UP, onMarqueeUp);
				
				var temp:BitmapData = new BitmapData(holder.width, holder.height);
				temp.draw(previous[edits], previous[edits].transform.matrix);
				
				saveLastInfo();
				
				previous[edits] = new Bitmap(new BitmapData(mrect.width, mrect.height), "auto", true);
				previous[edits].bitmapData.copyPixels(temp, mrect, new Point(0, 0));
				
				marq.graphics.clear();
				
				previous[edits].x = mrect.x;
				previous[edits].y = mrect.y;
				
				addChild(previous[edits]);
				setChildIndex(previous[edits], 0);
				
				
				
				removeEventListener(Event.ENTER_FRAME, updateMarquee);
				mrect = null;
			}
		}
		public function setMaxWidth(mw:Number):Number{
			if(previous[edits]){
				previous[edits].height = (mw/previous[edits].width) * previous[edits].height;
				previous[edits].width = mw;
			}
			return previous[edits].height;
		}
		public function setMaxHeight(mh:Number):Number{
			if(previous[edits]){
				previous[edits].width = (mh/previous[edits].height) * previous[edits].width;
				previous[edits].height = mh;
			}
			return previous[edits].width;
		}
		public function set forceDimension(o:Object):void {
			fdimension = o;
			
		}
		public function get forceDimension():Object {
			return fdimension;
		}
		public function set hue(n:Number):void {
			_hue = n;
			applyColors();
		}
		public function get hue():Number {
			return _hue;
		}
		public function set brightness(n:Number):void {
			_brightness = n;
			applyColors();
		}
		public function get brightness():Number {
			return _brightness;
		}
		public function set saturation(n:Number):void {
			_saturation = n;
			applyColors();
		}
		public function get saturation():Number {
			return _saturation;
		}
		public function set contrast(n:Number):void {
			_contrast = n;
			applyColors()
		}
		public function get contrast():Number {
			return _contrast;
		}
		override public function set source(src:String):void {
			isource = src;
			
			super.source = isource;
		}
		
		
		
	}
	
}